home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks96
/
FlyPaper.sit
/
Fly Paper
/
FlyPaper Source
/
App Sources
/
FlyPaperApp.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-22
|
9KB
|
393 lines
#include <new.h>
#ifndef FLYPAPERAPP_H
#include "FlyPaperApp.h"
#endif
#ifndef FLYPAPERINIT_H
#include "FlyPaperINIT.h"
#endif
#ifndef MAGICWINDOW_H
#include "MagicWindow.h"
#endif
#ifndef FLYPAPERUTILS_H
#include "FlyPaperUtils.h"
#endif
#ifndef CLIPPINGFILE_H
#include "ClippingFile.h"
#endif
#ifndef CLIPPINGWINDOW_H
#include "ClippingWindow.h"
#endif
#ifndef FLYPAPERERRORS_H
#include "FlyPaperErrors.h"
#endif
#include <Fonts.h>
#include <Resources.h>
#include <ToolUtils.h>
#include <Windows.h>
#include <Gestalt.h>
#include <TextServices.h>
#include <drag.h>
#include "Patches.h"
#include "Filter.h"
#include "Floaters.h"
Boolean gHasColorQD;
Boolean gRunning = true;
Ptr gFilterProc = nil;
FlyPaperGestaltPtr gFlyPaperINITData = nil;
GlobalsRec glob;
short gResFile = -1;
Str255 gClippingsFolderName;
FSSpec** gPendingFiles = nil;
short gNumPendingFiles = 0;
ProcessSerialNumber gMyPSN;
void CheckGestalts (void);
pascal OSErr UniversalAEHandler (AppleEvent* theEvent, AppleEvent* theReply, long refCon);
void Initialize (void);
void EventLoop ();
void CheckForNewClippings ();
void LoadClippings ();
FlyPaperGestaltPtr GetINITData ()
{
if (gFlyPaperINITData == NULL) {
Gestalt (kSignature, (long*) &gFlyPaperINITData);
}
return gFlyPaperINITData;
}
void CheckGestalts (void)
{
long gestaltResponse;
OSErr error;
error = Gestalt (gestaltQuickdrawFeatures, &gestaltResponse);
if (error)
throw error;
gHasColorQD = gestaltResponse & (1 << gestaltHasColor);
error = Gestalt (gestaltDragMgrAttr, &gestaltResponse);
if (error)
throw kNoDragManagerErr;
}
pascal
OSErr UniversalAEHandler (AppleEvent* theEvent, AppleEvent* theReply, long refCon)
{
if (refCon == kAEQuitApplication)
gRunning = false;
return noErr;
}
static
void NewHandler ()
{
DebugStr ("\p ### New failed");
throw (OSErr) memFullErr;
}
void Initialize (void)
{
#if BGONLY
SetApplLimit (GetApplLimit() - 16384); // give us a 16K stack instead of 8K
#endif
MaxApplZone ();
InitGraf (&qd.thePort);
// Background-only apps are not supposed to do this, but it is necessary in order for
// FindServiceWindow to work correctly. ••• I am not 100% sure of the consequences!
InitFonts ();
InitMenus ();
TEInit (); // TextBox requires this.
#if !BGONLY
InitFonts ();
InitWindows ();
InitMenus ();
TEInit ();
InitDialogs (NULL);
#endif
// remember our PSN for later
ProcessInfoRec pInfo;
ProcessSerialNumber psn = { 0, kCurrentProcess };
pInfo.processInfoLength = sizeof (pInfo);
pInfo.processName = nil;
pInfo.processAppSpec = nil;
OSErr error = GetProcessInformation (&psn, &pInfo);
if (error)
throw error;
gMyPSN = pInfo.processNumber;
gPendingFiles = (FSSpec**) TempNewHandle (0, &error);
if (error)
throw error;
// Remember our app's res file
gResFile = CurResFile ();
GetIndString (gClippingsFolderName, kMiscStrs, kClippingsFolderStr);
if (gClippingsFolderName [0] == '\0')
throw resNotFound;
// Install our AppleEvent handlers
AEEventHandlerUPP proc = NewAEEventHandlerProc (UniversalAEHandler);
if (!proc)
throw memFullErr;
error = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, proc, kAEOpenApplication, false);
if (error)
throw error;
error = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, proc, kAEOpenDocuments, false);
if (error)
throw error;
error = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, proc, kAEPrintDocuments, false);
if (error)
throw error;
error = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, proc, kAEQuitApplication, false);
if (error)
throw error;
GetCurrentProcess (&glob.myPSN);
// Install our patches (local to this process, of course)
if (gHasColorQD)
PatchNewWindow ();
PatchExitToShell ();
// Install the GNEFilter
gFilterProc = InstallEventFilter ((FilterHelperUPP) EventFilterHelper, (Ptr) GetCurrentA5 ());
if (!gFilterProc)
throw memFullErr;
}
void Finalize (void)
{
// do any panic cleanup
static Boolean beenHereDoneThat = false;
try {
if (!beenHereDoneThat) { // prevent potential recursion
beenHereDoneThat = true;
CloseRemainingFloaters();
if (gFilterProc) {
ReleaseEventFilter(gFilterProc);
gFilterProc = false;
}
if (gPendingFiles) {
gNumPendingFiles = 0;
DisposeHandle ((Handle) gPendingFiles);
gPendingFiles = nil;
}
}
} catch (...) {
}
}
void EventLoop ()
{
Boolean floaterEvent;
// If there are no internal events pending, then we call WNE() with a
// moderate delay. Otherwise, we want to make a fast response to any
// floater events, so we make sure the event filter will wake us up quickly.
if (! glob.forwardedEvents.qHead)
WaitNextEvent(everyEvent, &glob.theEvent, 60 * 5, 0);
// If nothing to do, then check our private event queue to see if any
// clicks or keydowns are pending for our floater windows.
floaterEvent = (glob.theEvent.what != nullEvent) ? false :
GetFloaterEvent(&glob.theEvent);
// Check the states of our floaters, then generate and handle any
// pending Update Events for floaters because the Event Mgr will
// not generate them for us.
ShowHideFloater(0);
UpdateFloater(0);
switch (glob.theEvent.what) {
case nullEvent : break;
case mouseDown :
short thePart;
Rect bounds;
WindowPtr whichWin, frontWin;
if (floaterEvent) {
thePart = FindServiceWindow (glob.theEvent.where, &whichWin);
if (GetFrontServiceWindow (&frontWin))
frontWin = nil;
} else {
thePart = FindWindow (glob.theEvent.where, &whichWin);
frontWin = FrontWindow();
}
glob.theEvent.message = thePart;
switch(thePart) {
case inMenuBar : break;
case inSysWindow : SystemClick(&glob.theEvent, whichWin); break;
case inGoAway :
if (TrackGoAway (whichWin, glob.theEvent.where))
DisposeFloater (whichWin);
break;
case inDrag:
case inGrow :
case inZoomIn :
case inZoomOut :
if (whichWin != frontWin) {
SelectWindow (whichWin);
UpdateFloater (whichWin);
}
bounds = (**GetGrayRgn()).rgnBBox;
DragWindow (whichWin, glob.theEvent.where, &bounds);
UpdateFloater (whichWin);
break;
case inContent :
if (whichWin != frontWin) {
SelectWindow (whichWin);
UpdateFloater (whichWin);
}
EventDispatchFloaters (&glob.theEvent, whichWin);
break;
}
break;
case keyDown :
case autoKey :
gRunning = false;
break;
case updateEvt:
if (GetOneFloater ((WindowPtr) glob.theEvent.message, false))
EventDispatchFloaters (&glob.theEvent, (WindowPtr) glob.theEvent.message);
break;
case activateEvt:
break;
case kHighLevelEvent:
OSErr error = AEProcessAppleEvent(&glob.theEvent);
if (error)
throw error;
break;
}
try {
ProcessPendingFiles ();
} catch (...) {
}
}
void LoadClippings ()
{
CInfoPBRec pb;
FSSpec spec;
long dirID;
OSErr error = FlyPaperFindFolder (kOnSystemDisk, kClippingsFolder, true,
&pb.hFileInfo.ioVRefNum, &dirID);
if (error)
throw error;
pb.hFileInfo.ioNamePtr = spec.name;
spec.name [0] = 0;
spec.parID = dirID;
spec.vRefNum = pb.hFileInfo.ioVRefNum;
for (pb.hFileInfo.ioFDirIndex = 1; ; ++pb.hFileInfo.ioFDirIndex) {
pb.hFileInfo.ioDirID = dirID;
if (PBGetCatInfoSync (&pb))
break;
if (pb.hFileInfo.ioFlFndrInfo.fdType != kMyClippingType)
continue;
CClippingFile* file = new CClippingFile (spec);
try {
CClippingWindow* window = new CClippingWindow (file);
} catch (...) {
delete file;
throw;
}
}
}
void ProcessPendingFiles ()
{
if (gNumPendingFiles == 0)
return;
try {
for (short i = 0; i < gNumPendingFiles; ++i) {
FSSpec spec = (*gPendingFiles) [i];
CClippingFile* file = new CClippingFile (spec);
try {
CClippingWindow* window = new CClippingWindow (file);
} catch (...) {
delete file;
throw;
}
}
} catch (...) {
SetHandleSize ((Handle) gPendingFiles, 0);
gNumPendingFiles = 0;
throw;
}
SetHandleSize ((Handle) gPendingFiles, 0);
gNumPendingFiles = 0;
}
void QueueUpFileForProcessing (FSSpec* spec)
{
OSErr error = PtrAndHand (spec, (Handle) gPendingFiles, sizeof (FSSpec));
if (error)
throw error;
WakeUpProcess (&gMyPSN);
++gNumPendingFiles;
}
void main (void)
{
short fRefNum;
set_new_handler (NewHandler);
try {
CheckGestalts ();
Initialize ();
LoadClippings ();
CreateMagicWindow ();
while (gRunning)
EventLoop ();
Finalize ();
} catch (...) {
Finalize ();
}
}